package router

import (
	"jgt-oper/src/logger"
	"jgt-oper/src/util"
	"regexp"

	"github.com/facebookgo/inject"
	"github.com/go-session/gear-session"
	"github.com/go-session/mongo"
	"github.com/go-session/session"
	"github.com/spf13/viper"
	"github.com/teambition/gear"
)

// SvcRouterV1Handler 初始化svc/v1路由
func SvcRouterV1Handler(g *inject.Graph) *gear.Router {
	router := gear.NewRouter(gear.RouterOptions{
		Root:                  "/oper/svc/v1",
		IgnoreCase:            true,
		FixedPathRedirect:     true,
		TrailingSlashRedirect: true,
	})

	// session过滤器
	// 注册session中间件(mongo存储)
	msess := viper.GetStringMapString("session")
	router.Use(gearsession.New(
		session.SetCookieLifeTime(3600*24*3),
		session.SetCookieName(msess["svc_id"]),
		session.SetSign([]byte(msess["sign"])),
		session.SetStore(
			mongo.NewStore(
				msess["url"],
				msess["db"],
				msess["c"],
			),
		),
	))

	runMode := viper.GetString("run_mode")
	if runMode == util.ProdMode {
		var prefixRegexp = regexp.MustCompile(`^/oper/svc/v1/(login|logout)`)
		router.Use(func(ctx *gear.Context) error {
			var traceID string
			if v, err := ctx.Any(util.GetTraceIDKey()); err == nil && v != nil {
				traceID = v.(string)
			}

			store := gearsession.FromContext(ctx)
			userID, ok := store.Get(util.SessionUserIDKey)
			if ok {
				ctx.SetAny(util.GetUserIDKey(), userID)
			}

			if prefixRegexp.MatchString(ctx.Path) {
				return nil
			}

			if !ok || userID == nil {
				return gear.ErrUnauthorized.WithMsg("用户未登录")
			}

			enterpriseID, ok := store.Get(util.SessionEnterpriseIDKey)
			if ok {
				ctx.SetAny(util.GetEnterpriseIDKey(), enterpriseID)
			}

			userType, ok := store.Get(util.SessionUserTypeKey)
			if ok {
				ctx.SetAny(util.GetUserTypeKey(), userType)
			}

			logger.Access(traceID, util.TT(userID).String()).Infof("访问会话: %s,企业ID: %v,用户类型: %v", store.SessionID(), enterpriseID, userType)
			return nil
		})
	} else {
		router.Use(DefaultUserMiddleware)
	}

	SvcLoginMap(g, router)
	SvcDictionaryMap(g, router)
	SvcEnterpriseMap(g, router)
	SvcEnterpriseAccountMap(g, router)
	SvcUserMap(g, router)
	SvcAuthCodeMap(g, router)
	SvcEmployeeMap(g, router)
	return router
}
